package com.sugar.real.estate.module.business.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;

/**
 * <b>反射获取方法工具类</b>
 *
 * @author Y.sugar
 * @since 2023/4/11 13:48
 */
public class MethodUtil {

    /**
     * <b>在该类型与继承链中查找方法</b>
     *
     * @param cls           待查找的类型
     * @param methodName    期望获取的方法名
     * @param supportParent 是否支持查找超类方法 true获取  false否
     * @param paramTypes    期望获取的方法参数
     * @return 查找到的方法
     */
    public static Method find(Class<?> cls, String methodName, boolean supportParent, Class<?>... paramTypes) {
        while (cls != null) {
            try {
                return cls.getDeclaredMethod(methodName, paramTypes);
            } catch (NoSuchMethodException e) {
                if (!supportParent) break;
                cls = cls.getSuperclass();
            }
        }

        return null;
    }

    /**
     * <b>调用方法</b>
     *
     * @param obj        待调用的对象
     * @param methodName 期望调用的方法名
     * @param params     调用方法传递的参数值
     * @return 方法调用的结果
     */
    public static Object invoke(Object obj, String methodName, Object... params) {
        try {
            Method method = find(obj.getClass(), methodName, true, Arrays.stream(params).map(Object::getClass).toArray(Class[]::new));
            if (Objects.nonNull(method)){
                method.setAccessible(true);
                return method.invoke(obj, params);
            }
            return null;
        } catch (IllegalAccessException | InvocationTargetException e) {
            return null;
        }
    }
}
